﻿using System;
using System.Collections.Generic;


namespace Xant.Querier.Core
{

    [Serializable]
    public class ReduplicateMacroException : Exception
    {
        public ReduplicateMacroException(string message) : base(message)
        {
        }
        
    }

    public static class MacroStore
    {
        private static Dictionary<string, Macro> dict;

        static MacroStore()
        {
            dict = new Dictionary<string, Macro>();
        }

        public static void Register<T>(T type, string name) where T: Macro
        {
            if (dict.ContainsKey(name))
            {
                var msg = string.Format("The {{{0}}} Macro already existed, it related to type: {1}", name, type.GetType().FullName);
                throw new ReduplicateMacroException(msg);
            }
            dict.Add(name, type);
        }

        public static void Register<T>(T type) where T: Macro
        {
            Register(type, type.GetType().Name);
        }

        public static Macro Find(string name)
        {
            if (!dict.ContainsKey(name))
            {
                return null;
            }
            return dict[name];
        }

        public static bool IsRegistered(string name)
        {
            return dict.ContainsKey(name);
        }

    }

    public abstract class Macro : Factor
    {

        public object Execute()
        {
            throw new NotImplementedException();
        }
    }

    public abstract class Macro<T>: Factor
    {
        public abstract object Execute();

    }

    /// <summary>
    /// 三天前
    /// </summary>
    public class ThreeDaysAgo : Macro<DateTime>
    {
        public override object Execute()
        {
            return DateTime.Today.AddDays(-3);
        }
    }

    /// <summary>
    /// 十天前
    /// </summary>
    public class TenDaysAgo : Macro<DateTime>
    {
        public override object Execute()
        {
            return DateTime.Today.AddDays(-10);
        }
    }

    /// <summary>
    /// 十五天前
    /// </summary>
    public class FifteenDaysAgo : Macro<DateTime>
    {
        public override object Execute()
        {
            return DateTime.Today.AddDays(-15);
        }
    }

    /// <summary>
    /// 昨天
    /// </summary>
    public class Yesterday : Macro<DateTime>
    {
        public override object Execute()
        {
            return DateTime.Today.AddDays(-1);
        }
    }

    /// <summary>
    /// 今天
    /// </summary>
    public class Today : Macro<DateTime>
    {
        public override object Execute()
        {
            return DateTime.Today;
        }
    }

    /// <summary>
    /// 明天
    /// </summary>
    public class Tomorrow : Macro<DateTime>
    {
        public override object Execute()
        {
            return DateTime.Today.AddDays(1);
        }
    }

    /// <summary>
    /// 三天后
    /// </summary>
    public class ThreeDaysLater : Macro<DateTime>
    {
        public override object Execute()
        {
            return DateTime.Today.AddDays(3);
        }
    }

    /// <summary>
    /// 十天后
    /// </summary>
    public class TenDaysLater : Macro<DateTime>
    {
        public override object Execute()
        {
            return DateTime.Today.AddDays(10);
        }
    }

    /// <summary>
    /// 十五天后
    /// </summary>
    public class FifteenDaysLater : Macro<DateTime>
    {
        public override object Execute()
        {
            return DateTime.Today.AddDays(15);
        }
    }

    /// <summary>
    /// 上周同一天
    /// </summary>

    /// <summary>
    /// 下周同一天
    /// </summary>

    /// <summary>
    /// 上月同一天
    /// </summary>

    /// <summary>
    /// 下月同一天
    /// </summary>

    /// <summary>
    /// 上月同一天
    /// </summary>
    /// <summary>
    /// 下月同一天
    /// </summary>



    /// <summary>
    /// 本月第一天
    /// </summary>
    public class FirstDayOfThisMonth : Macro<DateTime>
    {
        public override object Execute()
        {
            DateTime today = DateTime.Today;
            return today.AddDays(1-today.Day);
        }
    }

    /// <summary>
    /// 本月最后一天
    /// </summary>
    public class LastDayOfThisMonth : Macro<DateTime>
    {
        public override object Execute()
        {
            DateTime date = DateTime.Today.AddMonths(1);
            return date.AddDays(-date.Day);
        }
    }

    /// <summary>
    /// 本年第一天
    /// </summary>
    public class FirstDayOfThisYear : Macro<DateTime>
    {
        public override object Execute()
        {
            return new DateTime(DateTime.Today.Year, 1, 1);
        }
    }

    /// <summary>
    /// 本年最后一天
    /// </summary>
    public class LastDayOfThisYear : Macro<DateTime>
    {
        public override object Execute()
        {
            return new DateTime(DateTime.Today.Year+1, 1, 1).AddDays(-1);
        }
    }

    /// <summary>
    /// 上月第一天
    /// </summary>
    public class FirstDayOfLastMonth : Macro<DateTime>
    {
        public override object Execute()
        {
            DateTime date = DateTime.Today.AddMonths(-1);
            return date.AddDays(1-date.Day);
        }
    }

    /// <summary>
    /// 上月最后一天
    /// </summary>
    public class LastDayOfLastMonth : Macro<DateTime>
    {
        public override object Execute()
        {
            DateTime date = DateTime.Today;
            return date.AddDays(-date.Day);
        }
    }

    /// <summary>
    /// 去年第一天
    /// </summary>
    public class FirstDayOfLastYear : Macro<DateTime>
    {
        public override object Execute()
        {
            return new DateTime(DateTime.Today.Year-1, 1, 1);
        }
    }

    /// <summary>
    /// 去年最后一天
    /// </summary>
    public class LastDayOfLastYear : Macro<DateTime>
    {
        public override object Execute()
        {
            return new DateTime(DateTime.Today.Year, 1, 1).AddDays(-1);
        }
    }


}
